# Notes on scope sets

## Basic Overview

- name each scope that the binding forms create
example:
 (lambda (x) (lambda (y) (lambda (x) x) (lambda (x) y)))
 ->
 (lambda (x^{0}) (lambda (y^{1}) (lambda (x^{2}) x) (lambda (x^{3}) y)))

- add that name to the 'set of scopes' annotation of each syntax node under the binder
example:
 (lambda (x^{0}) (lambda^{0} (y^{0,1}) (lambda^{0,1} (x^{0,1,2}) x^{0,1,2})
                                       (lambda^{0,1} (x^{0,1,3}) y^{0,1,3})))

or if we dont bother annotating lambda (for ease of reading):
 
 (lambda (x^{0}) (lambda (y^{0,1}) (lambda (x^{0,1,2}) x^{0,1,2})
                                   (lambda (x^{0,1,3}) y^{0,1,3})))

- variable resolution is done based on the scope sets
example:
To resolve the variable x^{0,1,2}
we look at every binder whose name is 'x', finding:
 x^{0}
 x^{0,1,2}
 x^{0,1,3}

for a binder x^BINDING to surround x^VARIABLE we require
* (rule-1) BINDING subset-of VARIABLE

there are two of these:
 x^{0}
 x^{0,1,2}

so the one to pick is
* (rule-2) the largest set is the one that binds a variable

* (rule-3) if there are multiple largest sets, throw an ambiguous variable binding error


## Macros

TODO: explain that macro use sites create a new scope and why


## Why do we want 'lazy syntax'?

Consider processing the following form

(let ((a^{s} 0))
 (mac <something-huge-here>))

to expand mac we have to add the scope s to all the nodes of our huge form. Recursing over all that syntax a lot of time so it's faster to simply tag the form with a promise to add those scopes when we process its content.


